
import java.util.ArrayList;
import java.util.List;

import objects.Subset;
import objects.ValidPosition;


public class Alignment implements Comparable<Alignment> {

	private Subset parent;
	private int alignmentID;
	private int start;
	private int count;
	private String targetFeatureID;
	private String type;
	private String cigarString;
	private List<ValidPosition> bounds;
	private ValidPosition maxBound;

	public Alignment(int start, int count) {
		intialize(0, "", "transcript", start, "", count);
	}

	public Alignment(int alignmentID, String targetFeatureID, String type,
			int start, String cigarString) {
		intialize(alignmentID, targetFeatureID, type, start, cigarString, 1);
		createBounds(cigarString);
	}

	protected void intialize(int id, String target, String type, int start,
			String cigarString, int count) {
		this.alignmentID = id;
		this.targetFeatureID = target;
		this.type = type;
		this.start = start;
		this.count = count;
		this.cigarString = cigarString;
		this.parent = null;
		this.maxBound = null;
		this.bounds = new ArrayList<ValidPosition>();
	}

	private void createBounds(String cigar) {
		for (int offset = 0; !cigar.isEmpty();) {
			int m = cigar.indexOf("M");
			int n = cigar.indexOf("N");
			if (m < 0 && n < 0)
				return;

			int places = 0;
			if (m > 0 && (m < n || n < 0)) {
				places = Integer.parseInt(cigar.substring(0, m));
				ValidPosition temp = new ValidPosition(start + offset, start
						+ offset + places);
				bounds.add(temp);
				if (maxBound == null)
					maxBound = new ValidPosition(temp.start, temp.end);
				if (maxBound.start > temp.start) {
					maxBound.start = temp.start;
				}
				if (maxBound.end < temp.end) {
					maxBound.end = temp.end;
				}
				cigar = cigar.substring(m + 1);
			} else {
				places = Integer.parseInt(cigar.substring(0, n));
				cigar = cigar.substring(n + 1);
			}
			offset += places;

		}
	}

	public boolean hasAlignment() {
		return alignmentID != 0;
	}

	public int getCount() {
		return count;
	}

	public int getAlignmentID() {
		return alignmentID;
	}

	public void setSubsetParent(Subset sub) {
		parent = sub;
	}

	public Subset getSubsetParent() {
		return parent;
	}

	public String getType() {
		return type;
	}

	public String getTargetFeatureID() {
		return targetFeatureID;
	}

	public int getStartPosition() {
		return start;
	}

	public String getCigarString() {
		return cigarString;
	}

	public ValidPosition getBounds() {
		return maxBound;
	}

	public List<ValidPosition> getValidPositions() {
		return bounds;
	}

	public boolean isSpliced() {
		return bounds.size() > 1;
	}

	@Override
	public boolean equals(Object o) {
		if (o instanceof Alignment) {
			return ((Alignment) o).start == start;
		}
		return false;
	}

	@Override
	public int compareTo(Alignment a1) {
		return this.start - a1.start;
	}
}
